package com.nowcoder.community.service.impl;

import co.elastic.clients.elasticsearch._types.SortOptions;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;
import com.nowcoder.community.dao.elasticsearch.DiscussPostRepository;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.service.ElasticSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.core.SearchHitSupport;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.SearchPage;
import org.springframework.data.elasticsearch.core.query.HighlightQuery;
import org.springframework.data.elasticsearch.core.query.Query;
import org.springframework.data.elasticsearch.core.query.highlight.Highlight;
import org.springframework.data.elasticsearch.core.query.highlight.HighlightField;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ElasticSearchServiceImpl implements ElasticSearchService {

    @Autowired
    private DiscussPostRepository discussPostRepository;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 新增一个帖子
     * 不仅往数据库里存一份
     * 也往ElasticSearch的引擎中存一份
     * @param discussPost
     */
    @Override
    public void saveDiscussPost(DiscussPost discussPost) {
        discussPostRepository.save(discussPost);
    }

    @Override
    public void deleteDiscussPost(int discussPostId) {
        discussPostRepository.deleteById(discussPostId);
    }

    @Override
    public SearchPage<DiscussPost> searchDiscussPost(String keyword, int current, int limit) {
        List<HighlightField> list = new ArrayList<>();
        list.add(new HighlightField("title"));
        list.add(new HighlightField("content"));

        Query searchQuery = NativeQuery.builder()
                .withQuery(QueryBuilders.queryString(fn -> fn.query(keyword).fields("title", "content")))
                .withSort(SortOptions.of(fn -> fn.field(q -> q.field("type").order(SortOrder.Desc))))
                .withSort(SortOptions.of(fn -> fn.field(q -> q.field("score").order(SortOrder.Desc))))
                .withSort(SortOptions.of(fn -> fn.field(q -> q.field("createTime").order(SortOrder.Desc))))
                .withPageable(PageRequest.of(current, limit))
                .withHighlightQuery(new HighlightQuery(new Highlight(list), DiscussPost.class))
                .build();

        SearchHits<DiscussPost> searchHits = elasticsearchTemplate.search(searchQuery, DiscussPost.class);
        SearchPage<DiscussPost> searchPages = SearchHitSupport.searchPageFor(searchHits, searchQuery.getPageable());

        return searchPages;
    }

}
